#!/system/bin/sh


# 参考及引用：
# -----------------------------------
# https://gitee.com/sharpeter/proot-ubuntu
# https://blog.csdn.net/qq_39586925/article/details/105653918?spm=1001.2014.3001.5501
#
# https://mirrors.tuna.tsinghua.edu.cn/
# https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/os/
# wget https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/os/ArchLinuxARM-aarch64-latest.tar.gz
# http://cdimage.ubuntu.com/ubuntu-core/22/stable/20220525.4/
# https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/
# 
# https://mirrors.tuna.tsinghua.edu.cn/lxc-images/images/ubuntu/focal/arm64/default/20220528_07%3A43/	用这个比较妥 100MB 左右
# https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/										这个是ubuntu官方的最简系统，不好用
# 
# 




# 系统切换补丁，比如从 deepin 切换到 ubuntu
export vmDistribution=
export LINUX_DISTRIBUTION=
export LINUXVersionName=


cd ${tools_dir}
# pwd
source ${tools_dir}/vm_config.sh
# source ${app_home}/droidvm_vars_setup.sh


function ver_unsupported() {
	echo -e "\n\n\n\n\n\n"
	echo "此版本已不再维护，请使用最新版本"
	echo "下载网址：https://gitee.com/droidvm/app"
	echo ""

	cd ${tools_dir}
	echo -e "此版本已不再维护，请使用最新版本\n\n下载网址：\nhttps://gitee.com/droidvm/app\n\n10秒后继续启动" > "../tmp/promptmsg.txt"
	echo2apk "#promptmsg"
	sleep 10
}
# ver_unsupported


script_pid=$$
pmadd $script_pid setup_linux.sh


echo "正在运行 setup_linux.sh (安卓终端)"
echo ""
echo "setup_linux.sh(pid: $script_pid)"
echo "当前设备的CPU架构: ${HOST_CPU_ARCH}"
echo "当前 linux 发行版: ${vmDistribution}"
# set
echo '===================================='




function exit_with_msg() {
	echo ""
	echo ""
	echo '===================================='
	echo $2

	echo "安装脚本即将退出, 但会启动telnetd以便您排查"
	t

	exit $1
}

function go_android_console() {
	while true
	do
	/system/bin/sh
	done
}

function get_android_usergroups() {
	id -G  | tr ' ' '\n'>${app_home}/tmp/app_groupids.txt
	id -Gn | tr ' ' '\n'>${app_home}/tmp/app_groupnames.txt
}

function is_cn_mainland_network() {
    UA_WGET="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
    URL_TO_GETIP=http://inip.in/ip.json
	ndkwget ${URL_TO_GETIP} \
	|${ALINKER64} "${tools_dir}/busybox/busybox" awk -F, '{ for(i=1; i<=NF; i++) print substr($i,2) }' \
	|grep -E 'country_code|\"ip\"' \
	|grep "\"CN\""
}

function do_start_vm() {
	if [ ! -f ${app_home}/droidvm_vars_github_proxy_http.rc ]; then
		is_cn_mainland_network

		if [ $? -eq 0 ]; then
			NETWORK_AREA=中国大陆
			cat <<- EOF > ${app_home}/droidvm_vars_github_proxy_http.rc
				export GITHUB_PROXY_HOST=$GITHUB_PROXY_HOST_DEFAULT
				export GITHUB_PROXY_HTTP=$GITHUB_PROXY_HTTP_DEFAULT
			EOF
		else
			NETWORK_AREA=非中国大陆地区
		fi
		echo " 当前网络所属地区: ${NETWORK_AREA}"
	fi

	# ./startvm.sh 2>&1 >$APP_STDIO_NAME <$APP_STDIO_NAME
	exec /system/bin/sh ./startvm.sh 2>&1
}

function setup_complete() {

	chmod 777 startvm.sh  #2>/dev/null
	chmod 777 run_once.sh #2>/dev/null

	# app_boot_config 默认设置
	echo "0">${app_home}/app_boot_config/cfg_autostart_audio_service.txt
	echo "0">${app_home}/app_boot_config/cfg_autostart_ifbrg_service.txt
	echo "0">${app_home}/app_boot_config/cfg_autostart_virgl_service.txt
	echo "0">${app_home}/app_boot_config/cfg_autostart_vpntr_service.txt

	pmdel $script_pid
	echo2apk '正在通过 proot 加载 linux 环境'
	do_start_vm
}



function dl_git_client() {
	echo2apk "正在下载 git_client"

	if [ ! -x ./git/git ]; then
		unzip_rlt=1

		tmpnam=git4android.tar.gz
		tmpUrl=https://gitee.com/droidvm/git4android/releases/download/v2.48.1/git4android.tar.gz
		echo "正在下载 ${tmpUrl}"

		echo "app_temp: ${app_temp}"
		ndkhttpsget $tmpUrl ${tmpnam}  2>&1
		httpget_rlt=$?
		if [ $httpget_rlt -ne 0 ]; then
			rm -rf ${app_temp}/$tmpnam
		else
			mv -f ${app_temp}/$tmpnam ./
			${app_home}/toybox tar xzf ${tmpnam} -C ./
			unzip_rlt=$?
		fi

		chmod a+x ${tools_dir}/git/*

		if [ ! -x ./git/git ] || [ $unzip_rlt -ne 0 ]; then
			exit_with_msg 5 "git_client 下载解压失败"
		fi

	fi

	export git_dir=${tools_dir}/git
	chmod a+x ${git_dir}/*
	export PATH=$PATH:${git_dir}
}

function update_ndktools() {
	echo2apk "正在下载 EX_NDK_TOOLS"

	TMP_SHORT_DIR=ex_ndk_tools-${CURRENT_VM_ARCH}
	if [ ! -d ${TMP_SHORT_DIR} ] || [ -f ${TMP_SHORT_DIR}.downloading ] || [ ! -d ./ndkpulseaudio ]; then
		rm -rf ${TMP_SHORT_DIR}
		touch  ${TMP_SHORT_DIR}.downloading
		GIT_CONFIG_NOSYSTEM=1 \
		git clone --template=${git_dir}/templates https://gitee.com/droidvm/${TMP_SHORT_DIR}.git 2>/dev/null
		httpget_rlt=$?
		if [ $httpget_rlt -ne 0 ]; then
			rm -rf ${TMP_SHORT_DIR}*
			rm -rf ${TMP_SHORT_DIR}.downloading
			# go_android_console
		else
			rm -rf ${TMP_SHORT_DIR}.downloading
			rm -rf ${TMP_SHORT_DIR}/git
			mv  -f ${TMP_SHORT_DIR}/*  ./
		fi
	fi
	chmod a+x ${tools_dir}/busybox/busybox

	if [ ! -x ${tools_dir}/busybox/busybox ]; then
		exit_with_msg 5 "EX_NDK_TOOLS 下载解压失败"
	fi

	# if [ ! -d ./ndkpulseaudio ]; then
	# 	unzip_rlt=1

	# 	tmpnam=ex_ndk_tools-${EX_NDK_TOOLS_VERSION}-${CURRENT_VM_ARCH}.tar.gz
	# 	tmpUrl=${APP_URL_DLSERVER}/${tmpnam}
	# 	echo "正在下载 ${tmpUrl}"

	# 	echo "app_temp: ${app_temp}"
	# 	ndkhttpsget $tmpUrl ${tmpnam}  2>&1
	# 	httpget_rlt=$?

	# 	if [ $httpget_rlt -ne 0 ]; then
	# 		rm -rf ${app_temp}/$tmpnam
	# 	else
	# 		mv -f ${app_temp}/$tmpnam ./
	# 		${app_home}/toybox tar xzf ${tmpnam} -C ./
	# 		unzip_rlt=$?
	# 	fi

	# 	if [ ! -d ./ndkpulseaudio ] || [ $unzip_rlt -ne 0 ]; then
	# 		exit_with_msg 5 "EX_NDK_TOOLS 下载解压失败"
	# 	fi

	# fi
	# chmod a+x ${tools_dir}/busybox/busybox
}

function xlorie_pre() {
	rm -rf ${tools_dir}/libXlorie.so
	(cd ${tools_dir} && ln -sf ${tools_dir}/xlorie/libXlorie.so libXlorie.so )
}

# 1). 准备一些工具
function zzprepare() {
	dl_git_client
	update_ndktools
	xlorie_pre
}

# 2). 备份、还原、或直接启动已安装的虚拟系统
#################################################################################

function backup_restore_pre() {

	# 备份到app内的镜像文件，路径: /exbin/tools/imgbak/bak_${CURRENT_OS_NAME}.tar.gz
	if [ -x backupvm.sh ]; then
		echo ""
		echo ""
		echo2apk "正在备份 虚拟系统，备份完成会自动重启，请稍候"

		pmdel $script_pid
		# ./backupvm.sh 2>&1 >$APP_STDIO_NAME <$APP_STDIO_NAME
		/system/bin/sh ./backupvm.sh 2>&1
		rm -rf ./backupvm.sh
	fi


	# 还原共分为以下5种情况(都会设置OSRESTORING)：
	# =============================================================================================================================================================================
	#              说明              | 镜像在本地的保存路径                              |  变量名称     | 还原完是否删除镜像  |    哪设置的
	# 1. 从sd卡内的镜像文件恢复系统  | /sdcard/*.tar.gz                                  |  FROM_SDCARD  | 否(用户放置的)      | ${app_home}/droidvm_main.sh
	# 2. 从 apk内带镜像文件恢复系统  | ${app_home}/roms/bak_ubuntu-arm64.tar.gz          |  FROM_APKIMG  | 是(apk释放的资源)   | ${tools_dir}/distributions/*/1_download.rc
	# 3. 从  下载的镜像文件恢复系统  | ${tools_dir}/*.tar.gz, 也即 ./*.tar.gz            |  FROM_NETIMG  | 是(太占空间)        | ${tools_dir}/distributions/*/1_download.rc 或 此脚本
	# 4. 从 app内的镜像文件恢复系统  | ${tools_dir}/imgbak/bak_${CURRENT_OS_NAME}.tar.gz |  FROM_APPIMG  | 否(用户备份的)      | 此脚本
	# 5. 关联打开的镜像文件恢复系统  | ${tools_dir}/roms/assoc_opened_img.dgz            |  FROM_OPNIMG  | 否(关联打开的)      | ${app_home}/droidvm_main.sh

	# 除上述情况以外，就是全新安装虚拟系统了，OSRESTORING 为空！
	# =============================================================================================================================================================================

	# 从关联打开的镜像文件恢复系统
	if [ "$OSRESTORING" == "FROM_OPNIMG" ]; then
		bakImgPath=`cat ${app_home}/tmp/rom_selected 2>/dev/null`
		if [ "${bakImgPath}" == "" ] || [ ! -f ${bakImgPath} ]; then
			echo "恢复包不存在，请重新导入"
			exit_with_msg 5 "恢复包不存在，请重新导入"
		fi

		echo "正在提取镜像信息: ${bakImgPath}"
		tar -xzOf ${bakImgPath}  ./etc/droidvm/bootup_scripts/droidvm_vars_setup.sh  > ${app_home}/droidvm_vars_setup.sh 2>/dev/null
		tar_rlt=$?
		filezie=`stat -c %s ${app_home}/droidvm_vars_setup.sh 2>/dev/null`
		if [ "$filezie" -lt 10 ]; then
			tar_rlt=2
		fi
		if [ $tar_rlt -ne 0 ]; then
			echo "恢复包无法识别 (安装程序只能识别虚拟电脑app备份的镜像文件)"
			exit_with_msg 5 "恢复包无法识别"
		fi

		pmdel $script_pid

		source vm_config.sh

		LINUX_TXT="您导入的系统镜像文件"
		LINUX_ZIP=${bakImgPath}
		UNZIP_ARG=-xzf

		rm -rf ./startvm.sh
		rm -rf ./restorevm.sh
	fi

	# 从sd卡内的镜像文件恢复系统
	if [ "$OSRESTORING" == "FROM_SDCARD" ]; then

		if [ ! -r /sdcard/ ]; then
			echo ""
			echo "正在申请 /sdcard/ 目录的访问权限"
			echo "#req_sdcard_rw" > ${NOTIFY_PIPE}

			# 等待SD卡可访问，30s超时
			timeout 30s /system/bin/sh -c 'while [ ! -r /sdcard/ ]; do sleep 0.3; done'

			if [ ! -r /sdcard/ ]; then
				exit_with_msg 4 "没有权限使用SD卡，虚拟电脑无法从其中读取恢复包"
			fi
			echo "ok"
		fi

		while true
		do
			echo ""
			echo ""

			# 弹窗选镜像
			rm -rf ${app_home}/tmp/rom_selected
			echo "#vmRomImgSelect" > ${NOTIFY_PIPE}

			# 30 秒超时
			ndkwaitfile 30 ${app_home}/tmp/rom_selected > /dev/null

			bakImgPath=`cat ${app_home}/tmp/rom_selected 2>/dev/null`
			if [ "${bakImgPath}" == "" ] || [ ! -f ${bakImgPath} ]; then
				echo "恢复包不存在，请将恢复包放到 /sdcard/ 目录中，文件名任意起"
				exit_with_msg 5 "恢复包不存在，请将恢复包放到 /sdcard/ 目录中，文件名任意起"
			fi

			echo "正在提取镜像信息: ${bakImgPath}"
			tar -xzOf ${bakImgPath}  ./etc/droidvm/bootup_scripts/droidvm_vars_setup.sh  > ${app_home}/droidvm_vars_setup.sh 2>/dev/null
			tar_rlt=$?
			filezie=`stat -c %s ${app_home}/droidvm_vars_setup.sh 2>/dev/null`
			if [ "$filezie" -lt 10 ]; then
				tar_rlt=2
			fi
			if [ $tar_rlt -ne 0 ]; then
				echo "恢复包无法识别 (安装程序只能识别虚拟电脑app备份的镜像文件)"
				sleep 3
				continue
			else
				echo "ok"
				break
			fi
		done

		pmdel $script_pid

		# ls -al ${app_home}/droidvm_vars_setup.sh
		# source ${app_home}/droidvm_vars_setup.sh
		# ./restorevm.sh 2>&1
		source vm_config.sh


		LINUX_TXT="/sdcard/ 目录中的系统镜像文件"
		LINUX_ZIP=${bakImgPath}
		UNZIP_ARG=-xzf

		rm -rf ./startvm.sh
		rm -rf ./restorevm.sh
	fi

	# 从 app内的镜像文件恢复系统
	if [ -x restorevm.sh ]; then

		pmdel $script_pid
		# ./restorevm.sh 2>&1 >$APP_STDIO_NAME <$APP_STDIO_NAME

		# ./restorevm.sh 2>&1
		source vm_config.sh
		LINUX_TXT="您之前备份的系统镜像文件"
		LINUX_ZIP=imgbak/bak_${CURRENT_OS_NAME}.tar.gz
		UNZIP_ARG=-xzf

		rm -rf ./startvm.sh
		rm -rf ./restorevm.sh

		OSRESTORING=FROM_APPIMG
	fi

}

function check_to_startvm() {
	backup_restore_pre

	# 已安装过虚拟系统，直接启动
	if [ -x startvm.sh ]; then
		echo2apk "正在启动"

		if [ -f ${APP_FILENAME_URLTOOLS} ]; then
			mkdir -p $LINUX_DIR/etc/droidvm/bootup_scripts/tools/ 2>/dev/null
			cp -f def_startvm.sh	startvm.sh
			chmod 755 startvm.sh  2>/dev/null
			cp -f startvm.sh $LINUX_DIR/etc/droidvm/bootup_scripts/tools/
		fi

		pmdel $script_pid

		do_start_vm
		exit 0
	fi

}

# 3). 安装虚拟系统
#################################################################################

function prompt_vminfo_msg() {
	donwload_promted=0
	if [ "$donwload_promted" != "0" ]; then
		return
	fi
	donwload_promted=1

	echo "   虚拟机信息: "
	echo "=========================================="
	echo "    LINUX_DIR: $LINUX_DIR"
	echo "HOST_CPU_ARCH: ${HOST_CPU_ARCH}"
	echo "  VM_CPU_ARCH: ${VM_CPU_ARCH}"
	echo "   CROSS_ARCH: ${CROSS_ARCH}"
	echo "  vmGraphicsx: ${vmGraphicsx}"
	echo ""

	echo -e "耗时 约${TIME_COST}分钟(下载+安装)。\n安装完成会自动进入桌面环境.\n\n请保持前台运行，等待安装完成\n请保持前台运行，等待安装完成\n请保持前台运行，等待安装完成\n\n安装过程中建议您不要操作手机\n如有电话或好友消息，请浮窗回复\n\n安装程序开启的进程数量较多，后台运行时容易被【省电机制】终止运行，安装失败会导致启动黑屏" > "../tmp/promptmsg.txt"
	echo2apk "#initprompt"
}

function do_donwload_rootfs() {
	if [ "$LINUX_URL" == "" ]; then
		return
	fi

	echo2apk "正在下载 linux 镜像包"
	echo '===================================='
	echo "镜像信息：$LINUX_TXT"
	echo "下载链接：$LINUX_URL"
	echo "下载文件：$LINUX_ZIP"
	echo ""
	echo "  发行版：$LINUX_DISTRIBUTION"
	echo "  版本号：$LINUX_ROOTFS_VER"
	echo "版本代号：$LINUXVersionName"
	echo ""

	# UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36"

	ndkhttpsget $LINUX_URL $LINUX_ZIP  2>&1
	httpget_rlt=$?
	if [ $httpget_rlt -ne 0 ]; then
		rm -rf ${app_temp}/$LINUX_ZIP
	else
		mv -f ${app_temp}/$LINUX_ZIP ./
	fi
}

function donwload_rootfs() {
	if [ "$OSRESTORING" != "" ]; then
		return
	fi

	TIME_COST=" 3"
	VM_CPU_ARCH=${CURRENT_VM_ARCH}
	CROSS_ARCH=0
	if [ "${HOST_CPU_ARCH}" != "${VM_CPU_ARCH}" ]; then
		CROSS_ARCH=1
	fi

	if [ "${vmGraphicsx}" == "1" ]; then
		# 安装图形界面
		if [ "${CROSS_ARCH}" == "1" ]; then
			TIME_COST="15"
		else
			TIME_COST="10"
		fi
	else
		# 不装图形界面
		if [ "${CROSS_ARCH}" == "1" ]; then
			TIME_COST=" 5"
		else
			TIME_COST=" 3"
		fi
	fi

	prompt_vminfo_msg

	LINUX_ZIP=不存在的文件名.gz

	# if [ $APP_RELEASE_INTERNAL -ne 0 ]; then
	# 	if [ ! -f $LINUX_ZIP ]; then
	# 		get_debug_image_url
	# 		do_donwload_rootfs
	# 	fi
	# fi

	if [[ $cliptextOnStartup == "zzvm://bakrom"* ]]; then	# => zzvm://bakrom
				source ${app_home}/droidvm_vars_setup.sh

				do_donwload_rootfs

				if [ -f $LINUX_ZIP ]; then
					OSRESTORING=FROM_NETIMG
				fi
	elif [[ $cliptextOnStartup == "zzvm://rootfs"* ]]; then	# => zzvm://rootfs
				source ${app_home}/droidvm_vars_setup.sh

				if [ "$LINUX_URL" == "" ]; then
					source  ${tools_dir}/distributions/${vmDistribution}/1_download.rc
				else
					do_donwload_rootfs
				fi
	else
		echo '===================================='
		source  ${tools_dir}/distributions/${vmDistribution}/1_download.rc
	fi

	rootfs_not_exist=0

	if [ "$LINUX_URL" == "" ]; then
		rootfs_not_exist=1
	fi
	if [ "$LINUX_ZIP" == "" ]; then
		rootfs_not_exist=1
	fi
	if [ ! -f $LINUX_ZIP ]; then
		rootfs_not_exist=1
	fi

	if [ "$rootfs_not_exist" == "1" ]; then
		echo2apk "linux 镜像包下载失败"
		exit_with_msg 4 "linux 镜像包下载失败，建议进群(1030919016)下载带恢复包的安装包"
		# exit 4
	fi

	chmod 666 $LINUX_ZIP
	echo "LINUX_ZIP => $LINUX_ZIP"
	ls -al $LINUX_ZIP

}


# 从 github 下载恢复包，因加速器经常封禁不让下载大文件，故 2025.04.18 去掉此功能了
function get_prebuild_bakimg_url_via_website() {

	NETWORK_AREA=
	LINUX_URL=
	LINUX_TXT="本地调试服务器"

	# tmp_base_url="http://192.168.1.5/apps/droidvm/droidvm.php?ver=1.0&cmd=getbakimgurl"

	is_cn_mainland_network
	if [ $? -eq 0 ]; then
		NETWORK_AREA=中国大陆
	else
		NETWORK_AREA=非中国大陆地区
	fi
	echo " 当前网络所属地区: ${NETWORK_AREA}"

	tmpfilename=bkimgUrl.rc
	tmp_base_url="http://droidvm.com/apps/droidvm/droidvm.php?ver=1.0&cmd=getbakimgurl&release=${APP_RELEASE_VERSION}&area=${NETWORK_AREA}"
	ndkhttpsget ${tmp_base_url} ${tmpfilename}  2>&1
	httpget_rlt=$?
	if [ $httpget_rlt -eq 0 ]; then
		. ${app_temp}/${tmpfilename}

		cat <<- EOF > ${app_home}/droidvm_vars_github_proxy_http.rc
			export GITHUB_PROXY_HOST=$GITHUB_PROXY_HOST
			export GITHUB_PROXY_HTTP=$GITHUB_PROXY_HTTP
		EOF
	fi
	rm -rf ${app_temp}/${tmpfilename}
	
}

function get_prebuild_bakimg_url_via_gitee {
	TMP_SHORT_DIR=rom-${LINUX_DISTRIBUTION}-${LINUX_ROOTFS_VER}-${CURRENT_VM_ARCH}
	export PATH=$PATH:/data/user/0/com.zzvm/files/git

	LINUX_TXT="gitee仓库"
	LINUX_URL=https://gitee.com/droidvm/${TMP_SHORT_DIR}.git
	LINUX_ZIP=rootfs.tar.gz
	UNZIP_ARG=-xzf

	echo2apk "正在下载 linux 镜像包"
	echo '===================================='
	echo "镜像信息：$LINUX_TXT"
	echo "下载链接：$LINUX_URL"
	echo "下载文件：$LINUX_ZIP"
	echo ""
	echo "  发行版：$LINUX_DISTRIBUTION"
	echo "  版本号：$LINUX_ROOTFS_VER"
	echo "版本代号：$LINUXVersionName"
	echo ""

	echo "正在下载恢复包"
	# go_android_console
	httpget_rlt=$?
	if [ ! -d ${TMP_SHORT_DIR} ] || [ -f ${TMP_SHORT_DIR}.downloading ]; then
		rm -rf ${TMP_SHORT_DIR}
		touch  ${TMP_SHORT_DIR}.downloading
		GIT_CONFIG_NOSYSTEM=1 \
		git clone --template=${git_dir}/templates https://gitee.com/droidvm/${TMP_SHORT_DIR}.git # 2>/dev/null
		httpget_rlt=$?
		if [ $httpget_rlt -ne 0 ]; then
			rm -rf ${TMP_SHORT_DIR}*
			rm -rf ${TMP_SHORT_DIR}.downloading
			# go_android_console
		else
			rm -rf ${TMP_SHORT_DIR}.downloading
			echo "正在合并恢复包"
			cat ${TMP_SHORT_DIR}/ubuntu-24.04-1.55-arm64.tgz.* > $LINUX_ZIP
			OSRESTORING=FROM_NETIMG
		fi
	fi
}

function get_prebuild_bakimg() {
	# echo "cliptextOnStartup: $cliptextOnStartup"
	# sleep 10
	if [[ $cliptextOnStartup != "zzvm://setup"* ]] && [[ $cliptextOnStartup != "zzvm://setupex"* ]]; then

		# 尝试从gitee仓库下载
		get_prebuild_bakimg_url_via_gitee

		# 检测apk内带恢复包是否存在
		if [ ! -f $LINUX_ZIP ]; then
			if [ -f ${app_home}/roms/bak_${vmDistribution}-arm64.tar.gz ]; then
				LINUX_TXT="apk内带恢复包"
				LINUX_ZIP=bak_${vmDistribution}-arm64.tar.gz
				LINUX_URL=${app_home}/roms/$LINUX_ZIP
				UNZIP_ARG=-xzf

				cp -f ${app_home}/roms/bak_${vmDistribution}-arm64.tar.gz  $LINUX_ZIP
			fi

			if [ -f $LINUX_ZIP ]; then
				OSRESTORING=FROM_APKIMG
			fi
		fi

		# 尝试从github上下载恢复包，因加速器经常封禁不让下载大文件，故 2025.04.18 去掉此功能了
		if [ 0 -eq 1 ]; then
			if [ ! -f $LINUX_ZIP ]; then
				get_prebuild_bakimg_url_via_website
				do_donwload_rootfs

				if [ -f $LINUX_ZIP ]; then
					OSRESTORING=FROM_NETIMG
				fi
			fi
		fi

	fi
}


function hardlink_to_softlink() {
	echo "正在处理文件硬链接"
	while read line
	do
		if [[ "$line" != *"Cannot hard link to"* ]]; then
			echo "skip $line"
			continue
		fi

		# tar: ./usr/bin/uncompress: Cannot hard link to ‘./usr/bin/gunzip’: Permission denied
		line=`echo $line|sed 's|‘| |g'|sed 's|’| |g'|sed 's|:| |g'`
		TAGNAME=`echo "$line"|${ALINKER64} "${tools_dir}/busybox/busybox" awk -F'[ ]+' '{print $2}'`
		SRCFILE=`echo "$line"|${ALINKER64} "${tools_dir}/busybox/busybox" awk -F'[ ]+' '{print $7}'`
		SRCFILE=${SRCFILE:1}
		echo "硬链处理: |$SRCFILE|  |$TAGNAME|"
		(cd $LINUX_DIR && ln -sf $SRCFILE  $TAGNAME )
	done < ./unzipmsg.txt

	echo "文件硬链接已处理"
}

function unzip_via_thirdpart_tar() {
	echo "正在使用原生tar解压"
	rm -rf ./unzipmsg.txt
	rm -rf $LINUX_DIR
	mkdir -p $LINUX_DIR
	mkdir -p  $LINUX_DIR/tmp
	chmod 777 $LINUX_DIR/tmp

	# 使用第三方 tar 工具来解压 rootfs，完了要自己处理文件硬链接
	# 已确认: /system/bin/tar 和 busybox.tar 都无法正常解压 rootfs
	tar_dir=${tools_dir}/ndktar
	chmod a+x ${tar_dir}/*
	if [ ! -x ${tar_dir}/tar ]; then
		ls -al ${tar_dir}/	 > ./unzipmsg.txt
		echo "解压工具已损坏"					>> ./unzipmsg.txt
		return
	fi
	
	${ALINKER64} ${tar_dir}/tar --overwrite --preserve-permissions --exclude=dev $LINUX_EXC $UNZIP_ARG $LINUX_ZIP -C  $LINUX_DIR --hard-dereference 2>./unzipmsg.txt
	tar_rlt=1
	if [ ! -d "$LINUX_DIR/usr" ]; then
		mv unzipmsg.txt unzipmsg.txt.1
		return
	fi
	hardlink_to_softlink
	# 有 hardlink 以外的其它错误信息吗？若没有，则当成解压成功!!!!
	cat ./unzipmsg.txt|grep -v "Cannot hard link to"|grep -v "Exiting with failure status"
	if [ $? -ne 0 ]; then
		tar_rlt=0
	else
		mv unzipmsg.txt unzipmsg.txt.1
	fi
}

function unzip_in_proot_env() {
	echo "正在通过proot环境解压"
	rm -rf ./unzipmsg.txt
	rm -rf $LINUX_DIR
	mkdir -p $LINUX_DIR
	mkdir -p  $LINUX_DIR/tmp
	chmod 777 $LINUX_DIR/tmp

	chmod a+x ${tools_dir}/busybox/busybox

	${ALINKER64} ${PROOT_BINARY_DIR}/proot --link2symlink --kill-on-exit -0 -r $LINUX_DIR -w / -b /proc -b /system -b /apex -b ${tools_dir}:/exbin -b /sdcard:/exbin/sdcard \
	"/exbin/busybox/busybox" tar --exclude='dev' $LINUX_EXC $UNZIP_ARG /exbin/$LINUX_ZIP -C / 2>&1
	tar_rlt=$?
}

function unzip_internal() {
	unzip_via_thirdpart_tar
	if [ $tar_rlt -eq 0 ]; then return; fi
	echo "快速解压失败，正在通过proot环境进行慢速解压"
	unzip_in_proot_env
}

function unzip_rootfs() {
	echo "LINUX_TXT: |"$LINUX_TXT"|"
	echo "LINUX_ZIP: |"$LINUX_ZIP"|"
	echo "LINUX_URL: |"$LINUX_URL"|"
	echo "UNZIP_ARG: |"$UNZIP_ARG"|"

	echo ""
	echo ""
	echo2apk "正在解压系统文件, apk release ver: ${APP_RELEASE_VERSION}"
	echo "这个过程可能要3~5分钟的时间"
	echo "解压过程中请保持前台运行，不要关闭软件"
	echo "解压过程中请保持前台运行，不要关闭软件"
	echo "解压过程中请保持前台运行，不要关闭软件"
	echo "解压过程中请保持前台运行，不要关闭软件"
	echo "解压过程中请保持前台运行，不要关闭软件"

	tar_rlt=2
	chmod 755 ${PROOT_BINARY_DIR}/*
	# chmod 755 ${PROOT_BINARY_DIR}/loader/*

	if [ "$OSRESTORING" != "" ]; then
		LINUX_EXC="--exclude=exbin"
	fi

	echo "当前时间：" `date '+%T'`
	time unzip_internal

	rm -rf ${app_home}/tmp/rom_selected

	echo "解压返回值: |$tar_rlt|""当前时间：" `date '+%T'`
	if [ $tar_rlt -ne 0 ]; then
		echo2apk "解压失败"
		cat ./unzipmsg.txt 2>/dev/null
		rm -rf $LINUX_DIR

		# 把无法解压的rootfs也删掉!
		if [ "$OSRESTORING" == "" ]; then
			rm -rf $LINUX_ZIP
		fi
		if [ "$OSRESTORING" == "FROM_NETIMG" ]; then
			rm -rf $LINUX_ZIP
		fi

		exit_with_msg 5 "解压失败"
		# exit 5
	else
		if [ "$OSRESTORING" == "" ]; then
			rm -rf $LINUX_ZIP
		fi
		if [ "$OSRESTORING" == "FROM_NETIMG" ]; then
			rm -rf $LINUX_ZIP
		fi
		echo2apk "解压完成"
	fi
}

function start_rootfs() {
	get_android_usergroups

	if [ "$OSRESTORING" != "" ]; then

		echo2apk "正在清除恢复包中的老旧文件"

		rm -rf $LINUX_DIR/exbin
		rm -rf $LINUX_DIR/home/droidvm/.droidvm
		rm -rf $LINUX_DIR/home/droidvm/.config/gtk2
		rm -rf $LINUX_DIR/etc/hosts.user

		if [ "$OSRESTORING" == "FROM_APPIMG" ]; then
			echo "系统还原已完成."
			echo "系统还原已完成." > $LINUX_DIR/tmp/osrestoremsg.txt
		fi
	else
		# 全新安装
		cp -f def_startvm.sh	startvm.sh
		source  ${tools_dir}/distributions/${vmDistribution}/1_run_after_setup.rc
	fi

	cp -f def_startvm.sh	startvm.sh
	setup_complete
}

function setupvm() {
	if [ "$OSRESTORING" == "" ]; then
		echo2apk "正在安装 虚拟系统" # (删除ipc目录可手动安装)
	else
		echo2apk "正在还原 虚拟系统，还原完成会自动重启，请稍候"
		echo "img: |$LINUX_ZIP|"
	fi

	chmod -R 777 $LINUX_DIR 2>/dev/null
	rm -rf $LINUX_DIR       2>/dev/null
	mkdir $PROOT_TMP_DIR
	chmod 777 $PROOT_TMP_DIR
	
	# 下载镜像时的临时保存目录
	mkdir -p ../tmp

	donwload_rootfs
	unzip_rootfs
	start_rootfs
}


# 环境变量安装
function vm_setup_etc_profile_vars() {
	echo2apk "正在添加 $LINUX_DIR 中的自启动脚本"

	mkdir -p $LINUX_DIR/etc/profile.d 2>/dev/null
	tmpfile=$LINUX_DIR/etc/profile.d/droidvm.sh
	echo "source /exbin/tools/vm_config.sh"								> $tmpfile
	echo "alias unlink=rm"												>>$tmpfile
	echo "alias ls='ls --color=auto'"									>>$tmpfile
	echo "export PS1='"'\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '"'" >>$tmpfile
	chmod 750 $tmpfile
}

function vm_setup_hostname() {
	echo "DroidVM" >     $LINUX_DIR/etc/hostname
}

function vm_setup_add_binfmt_for_box64() {
	# binfmt.d
	mkdir -p   $LINUX_DIR/etc/binfmt.d  2>/dev/null
	chmod 777  $LINUX_DIR/etc/binfmt.d
}

function vm_add_vars() {
	vm_setup_etc_profile_vars
	vm_setup_hostname
	vm_setup_add_binfmt_for_box64

	cp -f   ${tools_dir}/distributions/${vmDistribution}/2_run_once.sh	     run_once.sh
	cp -f   ${tools_dir}/distributions/${vmDistribution}/3_setup-gui.sh	     setup-gui.sh
	cp -f   ${tools_dir}/distributions/${vmDistribution}/3_setup-gui-min.sh	 setup-gui-min.sh
}

zzprepare
check_to_startvm
setupvm


